﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace AsteroidWar
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        private int wayEnemyToSpawnBoss = 2;
        private float playerWinDelayTimer = 8f;
        private Vector2 offScreen = new Vector2(-500, -500);
        private Random rand = new Random();
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Boolean bossSound = true;
        enum Gamestates { TitleScreen, Mainmenu, Playing, Demo, PlayerDead, GameOver, WinGame };
        Gamestates gameStates = Gamestates.TitleScreen;
        private int winEffectTime = 0;
        private float gameWinTime = 0;
        Texture2D titleScreen;
        Texture2D spriteSheet;
        Texture2D asteroidSprite;
        Texture2D playerSprite;
        Texture2D shotSprite;
        Texture2D nebulaSprite;
        Texture2D enemySprite;
        Texture2D bossSprite;
        Texture2D explosionSprite;
        bool win = false;
        SpriteFont scoreFont;
        float winTime = 0f;
        Boolean pause = false;
        StarField starField;
        AsteroidManager asteroidManager;
        PlayerManager firstPlayer;
        SecondPlayer secondPlayer;
        EnemyManager enemyManager;
        Nebula nebula;

        CollisionManager collisionManager;
        ExplosionManager explosionManager;

        private float bossDeadDelayTime = 0;
        SaveGameManager saveGameManager;
        MenuManager menuManager;
        QuitMenu quitMenu;
        DemoManager demoManager;
        int scceenWidht = 800;
        int screenHeight = 600;
        //Use these timers for update images in game
        private float gameOverTime = 0;
        private float playerDeathDelayTimer = 2f;
        private float firstPlayerDeathTimer = -1;
        private float secondPlayerDeathTimer = -1;
        private float titleScreenTimer = 0f;
        private float titleScreenDelayTimer = 1f;

        private UI.ProgressBar bossHealthBar;
        private int playerStartingLives = 3;
        private Vector2 firstPlayerLocation = new Vector2(250, 550);
        private Vector2 secondPlayerLocation = new Vector2(500, 550);
        private Vector2 scoreLocation = new Vector2(20, 10);
        private Vector2 livesLocation = new Vector2(20, 25);

        private Vector2 scoreLocation2 = new Vector2(550, 10);
        private Vector2 livesLocation2 = new Vector2(550, 25);
       
        private void resetFirstPlayer()
        {
            firstPlayer.playerSprite.Location = firstPlayerLocation;
            firstPlayer.Destroyed = false;
            firstPlayer.deadTime = 0;
            firstPlayer.firstDead = true;
            
        }
        private void resetSecondPlayer()
        {
            secondPlayer.playerSprite.Location = secondPlayerLocation;
            secondPlayer.Destroyed = false;
            secondPlayer.deadTime = 0f;
            secondPlayer.firstDead = true;
        }

        private void resetGame()
        {
            enemyManager.reset();
            asteroidManager.reset();
            win = false;
            winEffectTime = 0;
            winTime = 0;
            bossDeadDelayTime = 0;
            explosionManager = new ExplosionManager(
              explosionSprite,                    //Exposion and particle texture
              new Rectangle(0, 0, 50, 50),        //Explosion Frame animation
              3,                                  //Explosion frame quantity
              new Rectangle(0, 51, 2, 2)          //Particle frame animation
              );
            asteroidManager = new AsteroidManager(
               this.Window.ClientBounds.Width,     //screen Width
               this.Window.ClientBounds.Height,    //screen Height
               10,                                 //Asteroid quantity
               asteroidSprite,                     //Texture
               new Rectangle(0, 0, 64, 64),        //Frame animation
               10                                  //Frame quantity
               );

            
        }

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
    
            //Set size for game window
            this.graphics.PreferredBackBufferWidth = scceenWidht;
            this.graphics.PreferredBackBufferHeight = screenHeight;
            
            IsMouseVisible = true;
            //Set full screen
            //graphics.PreferMultiSampling = true;
            this.graphics.IsFullScreen = false;    
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here         
           
            base.Initialize();       
        }


        private void LoadMainmenu()
        {

        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            //Prepare all texture for game
            spriteBatch = new SpriteBatch(GraphicsDevice);
            titleScreen = this.Content.Load<Texture2D>(@"Textures\welcome2");
            spriteSheet = this.Content.Load<Texture2D>(@"Textures\SpriteSheet");
            asteroidSprite = this.Content.Load<Texture2D>(@"Textures\asteroid");
            playerSprite = this.Content.Load<Texture2D>(@"Textures\fighter-Archimedes7");
            shotSprite = this.Content.Load<Texture2D>(@"Textures\weapon-pulse");
            nebulaSprite = this.Content.Load<Texture2D>(@"Textures\nebula1");
            enemySprite = this.Content.Load<Texture2D>(@"Textures\Fighter-Shadow Scout2");
            bossSprite = this.Content.Load<Texture2D>(@"Textures\Boss7");
            explosionSprite = this.Content.Load<Texture2D>(@"Textures\explosion1");


            starField = new StarField(
                this.Window.ClientBounds.Width,     //screen Width
                this.Window.ClientBounds.Height,    //screen Height
                150,                                //Star quantity
                new Vector2(0, 30),                 //Velocity
                spriteSheet,                        //Texture
                new Rectangle(0, 450, 2, 2)         //Frame animation
            );

            asteroidManager = new AsteroidManager(
                this.Window.ClientBounds.Width,     //screen Width
                this.Window.ClientBounds.Height,    //screen Height
                10,                                 //Asteroid quantity
                asteroidSprite,                     //Texture
                new Rectangle(0, 0, 64, 64),        //Frame animation
                10                                  //Frame quantity
                );

            nebula = new Nebula(
                nebulaSprite,                       //Texture
                new Rectangle(0, 0, 512, 512),   //Frame animation
                4,                                  //Rows in texture
                4,                                  //Columns in texture
                new Vector2(0, 90),                 //Velocity
                this.GraphicsDevice.Viewport        //Viewport 
                );

            Vector2 playerLocation = new Vector2(this.Window.ClientBounds.Width / 2 - 86 / 2, this.Window.ClientBounds.Height - 78);
            firstPlayer = new PlayerManager(
                playerSprite,                       //Player Texture
                new Rectangle(0, 0, 86, 78),        //Player frame animation
                shotSprite,                         //Shot texture
                new Rectangle(0, 0, 41, 41),        //Shot frame animation
                3,                                  //Player frame quantity
                new Rectangle(0, 0,                 //The limited area
                    this.Window.ClientBounds.Width, 
                    this.Window.ClientBounds.Height),
                playerLocation                      //Initial player location
                );
            secondPlayer = new SecondPlayer(
                playerSprite,                       //Player Texture
                new Rectangle(0, 0, 86, 78),        //Player frame animation
                shotSprite,                         //Shot texture
                new Rectangle(0, 0, 41, 41),        //Shot frame animation
                3,                                  //Player frame quantity
                new Rectangle(0, 0,                 //The limited area
                    this.Window.ClientBounds.Width,
                    this.Window.ClientBounds.Height),
                playerLocation                      //Initial player location
                );
            
            enemyManager = new EnemyManager(
                enemySprite,                        //Guard ship texture
                new Rectangle(0, 0, 86, 73),        //Guard ship frame animation
                shotSprite,                         //Shot texture
                new Rectangle(0, 0, 41, 41),        //Shot frame animation
                1,                                  //Guard ship frame quantity
                firstPlayer,                      //Get player location for shotting
                secondPlayer,
                new Rectangle(0, 0,                 //The limited area
                    this.Window.ClientBounds.Width, 
                    this.Window.ClientBounds.Height),
                bossSprite,                         //Boss ship texture
                new Rectangle(0, 0, 201, 268)       //Boss ship frame animation
                );
            firstPlayer.setListEnemies(enemyManager.enemies);
            secondPlayer.setListEnemies(enemyManager.enemies);
            explosionManager = new ExplosionManager(
                explosionSprite,                    //Exposion and particle texture
                new Rectangle(0, 0, 50, 50),        //Explosion Frame animation
                3,                                  //Explosion frame quantity
                new Rectangle(0, 51, 2, 2)          //Particle frame animation
                );
            
            collisionManager = new CollisionManager(
                asteroidManager,
                firstPlayer,
                secondPlayer,
                enemyManager,
                explosionManager,
                enemyManager.boss
                );

            //SOUND, FONT, SAVE
            Sound.Initialize(Content);

            scoreFont = Content.Load<SpriteFont>(@"Fonts/Font");

            saveGameManager = new SaveGameManager();

            menuManager = new MenuManager(this.Content);
            quitMenu = new QuitMenu(this.Content);
            demoManager = new DemoManager(this.Content, this.GraphicsDevice.Viewport);

            bossHealthBar = new UI.ProgressBar(this, new Rectangle(250, 10, 300, 16));
            bossHealthBar.minimum = 0;
            bossHealthBar.maximum = 100;
           
            
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        /// 
        KeyboardState oldState;
        KeyboardState newState;
        private bool checkKeyBoardEsc()
        {
            newState = Keyboard.GetState();
            bool result = false;
            if (newState.IsKeyDown(Keys.Escape) && oldState != newState)
            {
                result = true;
            }
            if (newState.IsKeyDown(Keys.Escape) && oldState == newState)
            {
                result = false;
            }
            oldState = newState;
            return result;
        }

        private void setUpTexture(Texture2D texture1, Texture2D texure2, Rectangle playerFrame)
        {
            Vector2 playerLocation = new Vector2(this.Window.ClientBounds.Width / 2 - 86 / 2, this.Window.ClientBounds.Height - 78);
            firstPlayer = new PlayerManager(
                texture1,                            //Player Texture
                playerFrame,                        //Player frame animation
                shotSprite,                         //Shot texture
                new Rectangle(0, 0, 41, 41),        //Shot frame animation
                3,                                  //Player frame quantity
                new Rectangle(0, 0,                 //The limited area
                    this.Window.ClientBounds.Width,
                    this.Window.ClientBounds.Height),
                firstPlayerLocation                      //Initial player location
                );
            secondPlayer = new SecondPlayer(
                texure2,                            //Player Texture
                playerFrame,                        //Player frame animation
                shotSprite,                         //Shot texture
                new Rectangle(0, 0, 41, 41),        //Shot frame animation
                3,                                  //Player frame quantity
                new Rectangle(0, 0,                 //The limited area
                    this.Window.ClientBounds.Width,
                    this.Window.ClientBounds.Height),
                secondPlayerLocation                      //Initial player location
                );
            firstPlayer.setListEnemies(enemyManager.enemies);
            secondPlayer.setListEnemies(enemyManager.enemies);
            enemyManager = new EnemyManager(
               enemySprite,                        //Guard ship texture
               new Rectangle(0, 0, 86, 73),        //Guard ship frame animation
               shotSprite,                         //Shot texture
               new Rectangle(0, 0, 41, 41),        //Shot frame animation
               1,                                  //Guard ship frame quantity
               firstPlayer,                      //Get player location for shotting
               secondPlayer,
               new Rectangle(0, 0,                 //The limited area
                   this.Window.ClientBounds.Width,
                   this.Window.ClientBounds.Height),
               bossSprite,                         //Boss ship texture
               new Rectangle(0, 0, 201, 268)       //Boss ship frame animation
               );
            if (GameSettings._model == 1)
            {
                firstPlayer.dame = 2;
                firstPlayer.playerSpeed = 250;
                secondPlayer.dame = 2;
                secondPlayer.playerSpeed = 250;
            }
            if (GameSettings._model == 2)
            {
                firstPlayer.dame = 1;
                firstPlayer.playerSpeed = 500;
                secondPlayer.dame = 1;
                secondPlayer.playerSpeed = 500;
            }
            if (GameSettings._model == 3)
            {
                firstPlayer.dame = 3;
                firstPlayer.playerSpeed = 150;
                secondPlayer.dame = 3;
                secondPlayer.playerSpeed = 150;
            }



            collisionManager = new CollisionManager(
                asteroidManager,
                firstPlayer,
                secondPlayer,
                enemyManager,
                explosionManager,
                enemyManager.boss
                );
        }

        private void changeModel()
        {
            //Change model for player
            switch (GameSettings._model)
            {
                case 1:
                    setUpTexture(this.Content.Load<Texture2D>(@"Textures\fighter-Archimedes7"),
                                 this.Content.Load<Texture2D>(@"Textures\fighter-Archimedes71"),
                                 new Rectangle(0, 0, 86, 78));
                    //Trigger to exit loop
                    GameSettings._model = 0;
                    break;
                case 2:
                    setUpTexture(this.Content.Load<Texture2D>(@"Textures\Fighter-Viper Mk"),
                                 this.Content.Load<Texture2D>(@"Textures\Fighter-Viper Mk1"), 
                                 new Rectangle(0, 0, 86, 130));
                    GameSettings._model = 0;
                    break;
                case 3:
                    setUpTexture(this.Content.Load<Texture2D>(@"Textures\Shuttle-Raptor1"),
                                 this.Content.Load<Texture2D>(@"Textures\Shuttle-Raptor11"),
                                 new Rectangle(0,0,86,110));
                    GameSettings._model = 0;
                    break;
                default:
                    break;
            }
        }
        private Vector2 randomVector()
        {
            int randomX = rand.Next(100, 700);
            int randomY = rand.Next(100, 500);
            return new Vector2(randomX, randomY);
        }

        private void bigExplosion(Vector2 position, int maxR)
        {
            List<Vector2> explosePoint = new List<Vector2>();
            for (int r = 0; r < maxR; r+=10)
            {
                for (int i = 0; i < 360; i+=30)
                {
                    explosePoint.Add(new Vector2(position.X+(int)(r * Math.Cos(i)), position.Y+(int)(r * Math.Sin(i))));
                }

            }

            foreach (Vector2 point in explosePoint)
            {
                explosionManager.AddExplosionNoSound(point, new Vector2(1, 1) / 10);
            }
            Sound.playExplose();
            
        }

        private void destroyAllEnemy()
        {
            foreach (Sprite asteroid in asteroidManager.Asteroids)
            {
                explosionManager.AddExplosion(
                                asteroid.Center,
                                asteroid.Velocity / 10);

                asteroid.Location = offScreen;
            }
            asteroidManager.Asteroids.Clear();
            enemyManager.Active = false;
        }

        public void winEffect()
        {

            bigExplosion(randomVector(),70);
           
            /*explosionManager.AddExplosion(new Vector2(200, 50), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(220, 100), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(240, 150), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(280,100), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(320, 150), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(340, 100), new Vector2(1, 1) / 10);
            explosionManager.AddExplosion(new Vector2(360, 50), new Vector2(1, 1) / 10);*/
            //Explose all asteroid
            /*foreach (Sprite asteroid in asteroidManager.Asteroids)
            {
                explosionManager.AddExplosion(
                                asteroid.Center,
                                asteroid.Velocity / 10);

                asteroid.Location = offScreen;
            }
            */
        }

        private void QuickSave()
        {
            if (Keyboard.GetState().IsKeyDown(Keys.F5))
            {
                List<Vector2> playerLocation = new List<Vector2>();
                List<int> playerLife = new List<int>();
                List<long> playerScore = new List<long>();
                playerLocation.Add(firstPlayer.playerSprite.Location);
                playerLife.Add(firstPlayer.LiveRemaining);
                playerScore.Add(firstPlayer.PlayerScore);

                if (GameSettings._2players)
                {
                    playerLocation.Add(secondPlayer.playerSprite.Location);
                    playerLife.Add(secondPlayer.LiveRemaining);
                    playerScore.Add(secondPlayer.PlayerScore);
                }
                saveGameManager.InitiateSave(playerLocation, playerLife, playerScore);
            }          
        }

        private void QuickLoad()
        {
            if (Keyboard.GetState().IsKeyDown(Keys.F6))
            {
                saveGameManager.InitiateLoad();
                if (saveGameManager.hasSave)
                {
                    firstPlayer.playerSprite.Location = saveGameManager.saveData.Location[0];
                    firstPlayer.LiveRemaining = saveGameManager.saveData.Life[0];
                    firstPlayer.PlayerScore = saveGameManager.saveData.Score[0];
                    if (saveGameManager.saveData.Location.ToArray().Length == 2)
                    {
                        secondPlayer.playerSprite.Location = saveGameManager.saveData.Location[1];
                        secondPlayer.LiveRemaining = saveGameManager.saveData.Life[1];
                        secondPlayer.PlayerScore = saveGameManager.saveData.Score[1];
                    }
                }
            }
        }

        private void FullScreen()
        {
            if (Keyboard.GetState().IsKeyDown(Keys.F1))
            {
                this.graphics.IsFullScreen = (this.graphics.IsFullScreen == true) ? false : true;
                this.graphics.ApplyChanges();
            }
        }
        protected override void Update(GameTime gameTime)
        {

            FullScreen();
            if (GameSettings._1player) secondPlayer.LiveRemaining = -1;
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            MouseState mouse = Mouse.GetState();
            // TODO: Add your update logic here
            switch (gameStates)
            {
                case Gamestates.TitleScreen:
                    titleScreenTimer +=(float)gameTime.ElapsedGameTime.TotalSeconds;
                    
                    if (titleScreenTimer >= titleScreenDelayTimer)
                    {
                        //Change game state to playing
                        if ((Keyboard.GetState().IsKeyDown(Keys.Space)) || (Keyboard.GetState().IsKeyDown(Keys.Enter)))
                        {
                            firstPlayer.LiveRemaining = playerStartingLives;
                            firstPlayer.PlayerScore = 0;
                            secondPlayer.LiveRemaining = playerStartingLives;
                            secondPlayer.PlayerScore = 0;
                            resetFirstPlayer();
                            resetSecondPlayer();
                           
                            gameStates = Gamestates.Mainmenu;
                        }
                    }
                    break;
                case Gamestates.Mainmenu:
                    menuManager.Update(gameTime, mouse);
                    if (menuManager.isPlaying) gameStates = Gamestates.Playing;
                    if (menuManager.isDemo)
                    {
                        gameStates = Gamestates.Demo;
                    }
                    if (menuManager.isStop) this.Exit();

                    if (checkKeyBoardEsc())
                    {
                        this.Exit();
                    }    
                    break;
                case Gamestates.Demo:
                    
                    demoManager.Update(gameTime);

                    if (checkKeyBoardEsc() || demoManager.isStoped == false)
                    {
                        gameStates = Gamestates.Mainmenu;
                        Sound.StopBackGround();
                        menuManager.menuStates = MenuManager.MenuStates.Main;
                        menuManager.isPlaying = false;
                        menuManager.isDemo = false;
                        demoManager.stop();
                    }
                    break;
                case Gamestates.Playing:
                    if (pause == false)
                    {
                       
                        if (win)
                        {
                            if (winEffectTime == 10) gameStates = Gamestates.WinGame;
                            winTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                            if (winTime >=500)
                            {
                                winEffect();
                                winTime = 0;
                                winEffectTime++;
                            }

                        }
                        changeModel();
                        Sound.PlayBackground();
                        
                        //if ((float)gameTime.TotalGameTime.TotalSeconds > 1 && !enemyManager.boss.Destroyed) enemyManager.BossShowTime = true;
                        if (enemyManager.totalEnemyWay >= wayEnemyToSpawnBoss)
                        {
                            enemyManager.BossShowTime = true;
                            //Sound.playBossSound();
                        }
                        if (enemyManager.BossShowTime)
                        {
                            bossHealthBar.value = enemyManager.boss.health;
                            bossHealthBar.Update(gameTime);
                        }

                        //Update location and status of all objects in game              
                        nebula.Update(gameTime);
                        starField.Update(gameTime);
                        asteroidManager.Update(gameTime);
                        firstPlayer.Update(gameTime);
                        //Update second player in case of two player
                        if (GameSettings._2players)
                            secondPlayer.Update(gameTime);
                        enemyManager.Update(gameTime);
                        explosionManager.Update(gameTime);
                        collisionManager.CheckCollisions();
                        if (enemyManager.boss.Destroyed) enemyManager.resetBoss();
                        //Update all properties of player when his ship is destroyed
                        if (firstPlayer.Destroyed)
                        {
                            if (firstPlayer.firstDead)
                            {
                                firstPlayer.LiveRemaining--;
                                firstPlayer.firstDead = false;
                            }

                            if (firstPlayer.LiveRemaining < 0 && secondPlayer.LiveRemaining < 0)
                            {
                                gameStates = Gamestates.GameOver;
                                gameOverTime = 0;
                            }
                            else
                            {
                                if (!firstPlayer.firstDead)
                                {
                                    firstPlayer.deadTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
                                    if (firstPlayer.deadTime >= playerDeathDelayTimer && firstPlayer.LiveRemaining >= 0)
                                        resetFirstPlayer();
                                }

                            }
                        }
                        if (GameSettings._2players && secondPlayer.Destroyed)
                        {
                            if (secondPlayer.firstDead)
                            {
                                secondPlayer.LiveRemaining--;
                                secondPlayer.firstDead = false;
                            }

                            if (secondPlayer.LiveRemaining < 0 && firstPlayer.LiveRemaining < 0)
                            {
                                gameStates = Gamestates.GameOver;
                                gameOverTime = 0;
                            }
                            else
                            {
                                if (!secondPlayer.firstDead)
                                {
                                    secondPlayer.deadTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
                                    if (secondPlayer.deadTime >= playerDeathDelayTimer && secondPlayer.LiveRemaining >= 0)
                                        resetSecondPlayer();
                                }

                            }
                        }

                        QuickSave();
                        QuickLoad();

                    }
                    else
                    {
                        quitMenu.Update(gameTime, mouse);
                        if (quitMenu.quit == 1)
                        {
                            pause = false;
                            this.resetFirstPlayer();
                            this.resetSecondPlayer();
                            resetGame();
                            this.enemyManager.boss.sprite.Location = new Vector2(300, -300);
                            Sound.StopBackGround();
                            quitMenu.quit = 0;
                            gameStates = Gamestates.Mainmenu;
                            menuManager.menuStates = MenuManager.MenuStates.Main;
                            menuManager.isPlaying = false;
                        }
                        else if (quitMenu.quit == 2)
                        {
                            quitMenu.quit = 0;
                            pause = false;
                        }
                    }
                        //Exit to main menu
                        if (checkKeyBoardEsc())
                        {
                            if (pause == false)
                            {
                                pause = true;
                            }
                        }
                        if (enemyManager.boss.Destroyed)
                        {
                            destroyAllEnemy();
                            bossDeadDelayTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
                            if (bossDeadDelayTime>=3) win = true;
                        }

                        break;
                    
                case Gamestates.PlayerDead:
                    if (firstPlayer.Destroyed) firstPlayerDeathTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    if (secondPlayer.Destroyed) secondPlayerDeathTimer +=(float)gameTime.ElapsedGameTime.TotalSeconds;

                    //Update location and status of all objects in game
                    nebula.Update(gameTime);
                    starField.Update(gameTime);
                    if (!firstPlayer.Destroyed)
                        firstPlayer.Update(gameTime);
                    if (!secondPlayer.Destroyed)
                        secondPlayer.Update(gameTime);
                    asteroidManager.Update(gameTime);
                    enemyManager.Update(gameTime);
                    if (!firstPlayer.Destroyed) firstPlayer.PlayerShotManager.Update(gameTime);
                    if (!secondPlayer.Destroyed) secondPlayer.PlayerShotManager.Update(gameTime);
                    explosionManager.Update(gameTime);
                    collisionManager.CheckCollisions();
                    
                    if (firstPlayer.Destroyed && firstPlayer.LiveRemaining>0 && firstPlayerDeathTimer >= playerDeathDelayTimer)
                    {
                        resetFirstPlayer();
                        if (!secondPlayer.Destroyed || secondPlayer.LiveRemaining<=0) gameStates = Gamestates.Playing;
                    }
                    if (secondPlayer.Destroyed && secondPlayer.LiveRemaining>0 && secondPlayerDeathTimer >= playerDeathDelayTimer)
                    {
                        resetSecondPlayer();
                        if (!firstPlayer.Destroyed || firstPlayer.LiveRemaining<=0) gameStates = Gamestates.Playing;
                    }
                    break;
                   
                case Gamestates.GameOver:
                    gameOverTime +=(float)gameTime.ElapsedGameTime.TotalSeconds;

                    //Update location and status of all objects in game
                    starField.Update(gameTime);
                    asteroidManager.Update(gameTime);
                    enemyManager.Update(gameTime);
                    firstPlayer.PlayerShotManager.Update(gameTime);
                    explosionManager.Update(gameTime);

                    //Return to title screen
                    if (gameOverTime >= playerDeathDelayTimer)
                    {
                        //this.LoadContent();
                        resetGame();
                        this.enemyManager.boss.sprite.Location = new Vector2(300, -300);
                        this.resetFirstPlayer();
                        this.resetSecondPlayer();
                        Sound.StopBackGround();
                        gameStates = Gamestates.TitleScreen;
                        menuManager.menuStates = MenuManager.MenuStates.Main;
                        menuManager.isPlaying = false;
                    }
                    break;
                case Gamestates.WinGame:
                    gameWinTime += (float)gameTime.ElapsedGameTime.TotalSeconds;

                    //Update location and status of all objects in game
                    starField.Update(gameTime);
                    asteroidManager.Update(gameTime);
                    enemyManager.Update(gameTime);
                    firstPlayer.PlayerShotManager.Update(gameTime);
                    explosionManager.Update(gameTime);

                    //Return to title screen
                    if (gameWinTime >= playerWinDelayTimer)
                    {
                        //this.LoadContent();
                        gameWinTime = 0;
                        resetGame();
                        this.enemyManager.boss.sprite.Location = new Vector2(300, -300);
                        this.resetFirstPlayer();
                        this.resetSecondPlayer();
                        Sound.StopBackGround();
                        gameStates = Gamestates.TitleScreen;
                        menuManager.menuStates = MenuManager.MenuStates.Main;
                        menuManager.isPlaying = false;
                    }
                    break;
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here
            spriteBatch.Begin();

            if (gameStates == Gamestates.TitleScreen)
            {
                spriteBatch.Draw(
                 titleScreen,
                 new Rectangle(0, 0, 
                     this.Window.ClientBounds.Width, 
                     this.Window.ClientBounds.Height), 
                 Color.White);
            }
            if (gameStates == Gamestates.Mainmenu)
            {
                spriteBatch.Draw(titleScreen, new Rectangle(0, 0,this.Window.ClientBounds.Width,this.Window.ClientBounds.Height),Color.White);
                menuManager.Draw(spriteBatch);
            }
            if (gameStates == Gamestates.Demo)
            {
                demoManager.Draw(spriteBatch);
            }

            if (gameStates == Gamestates.Playing ||
                gameStates == Gamestates.PlayerDead ||
                gameStates == Gamestates.GameOver ||
                gameStates == Gamestates.WinGame)
            {
                
                nebula.Draw(spriteBatch);
                starField.Draw(spriteBatch);
                asteroidManager.Draw(spriteBatch);
                if (GameSettings._2players)
                    secondPlayer.Draw(spriteBatch);
                firstPlayer.Draw(spriteBatch);
                enemyManager.Draw(spriteBatch);
                explosionManager.Draw(spriteBatch);
                if (pause == true)
                {
                    Texture2D ground = this.Content.Load<Texture2D>(@"Textures\ground");
                    spriteBatch.Draw(ground, new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height), new Color(255, 255, 255, 100));
                    quitMenu.Draw(spriteBatch);       
                }
                //Draw player score board
                spriteBatch.DrawString(
                    scoreFont,
                    "Score: " + firstPlayer.PlayerScore.ToString(),
                    scoreLocation,
                    Color.White);

                if (GameSettings._2players)
                    spriteBatch.DrawString(
                    scoreFont,
                    "Player 2 Score: " + secondPlayer.PlayerScore.ToString(),
                    scoreLocation2,
                    Color.White);
                //Draw player life board
                if (firstPlayer.LiveRemaining >= 0)
                {
                    spriteBatch.DrawString(
                        scoreFont,
                        "Ships Remaining: " +
                            firstPlayer.LiveRemaining.ToString(),
                        livesLocation,
                        Color.White);
                }
                if (GameSettings._2players && secondPlayer.LiveRemaining >= 0)
                {
                    spriteBatch.DrawString(
                        scoreFont,
                        "Ships Remaining: " +
                            secondPlayer.LiveRemaining.ToString(),
                        livesLocation2,
                        Color.White);
                }
            }

            if (gameStates == Gamestates.GameOver)
            {
                //Draw the end game message
                spriteBatch.DrawString(
                    scoreFont,
                    "G A M E  O V E R !",
                    new Vector2(
                        this.Window.ClientBounds.Width / 2 -
                          scoreFont.MeasureString("G A M E  O V E R !").X / 2,
                        50),
                    Color.White);
            }
            if (gameStates == Gamestates.WinGame)
            {
                //Draw the end game message
                spriteBatch.DrawString(
                    scoreFont,
                    "Y O U W I N !",
                    new Vector2(
                        this.Window.ClientBounds.Width / 2 -
                          scoreFont.MeasureString("Y O U W I N !").X / 2,
                        50),
                    Color.Red);
            }
            //spriteBatch.DrawString(scoreFont, enemyManager.totalEnemyWay.ToString(), new Vector2(100, 100), Color.White);
            spriteBatch.End();
            if (enemyManager.BossShowTime) bossHealthBar.Draw(spriteBatch);
            base.Draw(gameTime);
        }
    }
}
